package com.lgmshare.component.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.ColorRes;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.content.ContextCompat;

import com.lgmshare.component.R;

public class NumberInputView extends AppCompatEditText implements TextWatcher {

    public interface ViewType {
        int ROUNDRECT = 1;
        int UNDERLINE = 2;
        int BIASLINE = 3;
    }

    private int mFigures;//需要输入的位数
    private int mInputMargin;//验证码之间的间距
    private int mBottomSelectedColor;//底部选中的颜色
    private int mBottomNormalColor;//未选中的颜色
    private float mBottomLineHeight;//底线的高度
    private int mBackgroundColor;//选中的背景颜色
    private int mSelectedBackgroundColor;//选中的背景颜色

    private OnInputChangedListener mOnInputChangedListener;
    private int mCurrentPosition = 0;
    private int mEachRectLength = 0;//每个矩形的边长
    private Paint mSelectedBackgroundPaint;
    private Paint mNormalBackgroundPaint;
    private Paint mBottomSelectedPaint;
    private Paint mBottomNormalPaint;

    private int mViewType = ViewType.ROUNDRECT;

    private boolean mShadowPasswords = false;
    private boolean mKeyboard = false;

    public NumberInputView(Context context) {
        this(context, null);
    }

    public NumberInputView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public NumberInputView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        super.addTextChangedListener(this);
        initAttrs(attrs);
        initPaint();
    }

    /**
     * 初始化paint
     */
    private void initPaint() {
        mSelectedBackgroundPaint = new Paint();
        mSelectedBackgroundPaint.setColor(mSelectedBackgroundColor);
        mNormalBackgroundPaint = new Paint();
        mNormalBackgroundPaint.setColor(mBackgroundColor);

        mBottomSelectedPaint = new Paint();
        mBottomNormalPaint = new Paint();
        mBottomSelectedPaint.setColor(mBottomSelectedColor);
        mBottomNormalPaint.setColor(mBottomNormalColor);
        mBottomSelectedPaint.setStrokeWidth(mBottomLineHeight);
        mBottomNormalPaint.setStrokeWidth(mBottomLineHeight);
    }

    /**
     * 初始化Attrs
     */
    private void initAttrs(AttributeSet attrs) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.NumberInputView);
        mFigures = ta.getInteger(R.styleable.NumberInputView_niv_figures, 4);
        mViewType = ta.getInteger(R.styleable.NumberInputView_niv_viewType, ViewType.UNDERLINE);
        mKeyboard = ta.getBoolean(R.styleable.NumberInputView_niv_keyboard, true);
        mInputMargin = (int) ta.getDimension(R.styleable.NumberInputView_niv_verCodeMargin, 0);
        mBottomSelectedColor = ta.getColor(R.styleable.NumberInputView_niv_bottomLineSelectedColor,
                getCurrentTextColor());
        mBottomNormalColor = ta.getColor(R.styleable.NumberInputView_niv_bottomLineNormalColor,
                getColor(android.R.color.darker_gray));
        mBottomLineHeight = ta.getDimension(R.styleable.NumberInputView_niv_bottomLineHeight,
                dp2px(5));
        mBackgroundColor = ta.getColor(R.styleable.NumberInputView_niv_backgroundColor,
                getColor(android.R.color.darker_gray));
        mSelectedBackgroundColor = ta.getColor(R.styleable.NumberInputView_niv_selectedBackgroundColor,
                getColor(android.R.color.darker_gray));
        ta.recycle();

        // force LTR because of bug: https://github.com/JustKiddingBaby/NumberInputView/issues/4
        setLayoutDirection(LAYOUT_DIRECTION_LTR);
        setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));//防止出现下划线
        if (mKeyboard) {
            setFocusableInTouchMode(true);
        }
    }


    @Override
    final public void setCursorVisible(boolean visible) {
        super.setCursorVisible(false);//隐藏光标的显示
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthResult = 0, heightResult = 0;
        //最终的宽度
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            widthResult = widthSize;
        } else {
            widthResult = getScreenWidth(getContext());
        }
        //每个矩形形的宽度
        mEachRectLength = (widthResult - (mInputMargin * (mFigures - 1))) / mFigures;
        //最终的高度
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            heightResult = heightSize;
        } else {
            heightResult = mEachRectLength;
        }
        setMeasuredDimension(widthResult, heightResult);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mKeyboard) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                requestFocus();
                setSelection(getText().length());
                showKeyBoard(getContext());
                return false;
            }
            return super.onTouchEvent(event);
        } else {
            return true;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mCurrentPosition = getText().length();
        int width = mEachRectLength - getPaddingLeft() - getPaddingRight();
        int height = getMeasuredHeight();

        float cx, cy = getMeasuredHeight() / 2;
        float half = getMeasuredWidth() / mFigures / 2;

        switch (mViewType) {
            case ViewType.ROUNDRECT:
                for (int i = 0; i < mFigures; i++) {
                    canvas.save();
                    int start = width * i + i * mInputMargin;
                    int end = width + start;
                    //画一个矩形
                    if (i == mCurrentPosition) {//选中的下一个状态
                        final Rect rect = new Rect(start, 0, end, height);
                        final RectF rectF = new RectF(rect);
                        canvas.drawRoundRect(rectF, 8, 8, mSelectedBackgroundPaint);
                    } else {
                        final Rect rect = new Rect(start, 0, end, height);
                        final RectF rectF = new RectF(rect);
                        canvas.drawRoundRect(rectF, 8, 8, mNormalBackgroundPaint);
                    }
                    canvas.restore();
                }
                break;
            case ViewType.UNDERLINE:
                //绘制底线
                for (int i = 0; i < mFigures; i++) {
                    canvas.save();
                    float lineY = height - mBottomLineHeight / 2;
                    int start = width * i + i * mInputMargin;
                    int end = width + start;
                    if (i < mCurrentPosition) {
                        canvas.drawLine(start, lineY, end, lineY, mBottomSelectedPaint);
                    } else {
                        canvas.drawLine(start, lineY, end, lineY, mBottomNormalPaint);
                    }
                    canvas.restore();
                }
                break;
            case ViewType.BIASLINE:
                int length = getText().toString().length();
                for (int i = length; i < mFigures; i++) {
                    canvas.save();
                    float x = getMeasuredWidth() * i / mFigures + half;
                    if (i < mCurrentPosition) {
                        canvas.drawLine(x + half / 8, getMeasuredHeight() / 2 - half / 4, x - half / 8,
                                getMeasuredHeight() / 2 + half / 4, mBottomSelectedPaint);
                    } else {
                        canvas.drawLine(x + half / 8, getMeasuredHeight() / 2 - half / 4, x - half / 8,
                                getMeasuredHeight() / 2 + half / 4, mBottomNormalPaint);
                    }
                    canvas.restore();
                }
                break;
            default:
                break;
        }

        if (mShadowPasswords) {
            //绘制文字
            String value = getText().toString();
            TextPaint paint = getPaint();
            paint.setTextAlign(Paint.Align.CENTER);
            paint.setColor(getCurrentTextColor());
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            for (int i = 0; i < value.length(); i++) {
                canvas.save();
                int start = width * i + i * mInputMargin;
                float x = start + width / 2;
                float baseline = (height - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
                canvas.drawText(String.valueOf(value.charAt(i)), x, baseline, paint);
                canvas.restore();
            }
        } else {
            //密码
            int radiusArc = dp2px(6);
            int length = getText().toString().length();
            Paint paint = getPaint();
            paint.setAntiAlias(true);
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(getCurrentTextColor());
            for (int i = 0; i < length; i++) {
                canvas.save();
                cx = getMeasuredWidth() * i / mFigures + half;
                canvas.drawCircle(cx, cy, radiusArc, paint);
                canvas.restore();
            }
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        mCurrentPosition = getText().length();
        postInvalidate();
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        mCurrentPosition = getText().length();
        postInvalidate();
        if (mOnInputChangedListener != null) {
            mOnInputChangedListener.onInputChanged(getText(), start, before, count);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        mCurrentPosition = getText().length();
        postInvalidate();
        if (getText().length() == mFigures) {
            if (mOnInputChangedListener != null) {
                mOnInputChangedListener.onInputCompleted(getText());
            }
        } else if (getText().length() > mFigures) {
            getText().delete(mFigures, getText().length());
        }
    }

    /**
     * 设置位数
     */
    public void setFigures(int figures) {
        mFigures = figures;
        postInvalidate();
    }

    /**
     * 设置输入框之间的间距
     */
    public void setInputMargin(int margin) {
        mInputMargin = margin;
        postInvalidate();
    }

    /**
     * 设置底部选中状态的颜色
     */
    public void setBottomSelectedColor(@ColorRes int bottomSelectedColor) {
        mBottomSelectedColor = getColor(bottomSelectedColor);
        postInvalidate();
    }

    /**
     * 设置底部未选中状态的颜色
     */
    public void setBottomNormalColor(@ColorRes int bottomNormalColor) {
        mBottomSelectedColor = getColor(bottomNormalColor);
        postInvalidate();
    }

    @Override
    public void setBackgroundColor(int backgroundColor) {
        mBackgroundColor = backgroundColor;
    }

    /**
     * 设置选择的背景色
     */
    public void setSelectedBackgroundColor(@ColorRes int selectedBackground) {
        mSelectedBackgroundColor = getColor(selectedBackground);
        postInvalidate();
    }

    /**
     * 设置底线的高度
     */
    public void setBottomLineHeight(int bottomLineHeight) {
        this.mBottomLineHeight = bottomLineHeight;
        postInvalidate();
    }


    /**
     * 设置当验证码变化时候的监听器
     */
    public void setOnInputChangedListener(OnInputChangedListener listener) {
        this.mOnInputChangedListener = listener;
    }

    /**
     * 返回颜色
     */
    private int getColor(@ColorRes int color) {
        return ContextCompat.getColor(getContext(), color);
    }

    /**
     * dp转px
     */
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getResources().getDisplayMetrics());
    }

    /**
     * 获取手机屏幕的宽度
     */
    static int getScreenWidth(Context context) {
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

    public void showKeyBoard(Context context) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
    }

    public void setInputViewType(int viewType) {
        mViewType = viewType;
    }

    public void setShadowPasswords(boolean shadowPasswords) {
        mShadowPasswords = shadowPasswords;
    }

    /**
     * 验证码变化时候的监听事件
     */
    public interface OnInputChangedListener {

        /**
         * 当验证码变化的时候
         */
        void onInputChanged(CharSequence s, int start, int before, int count);

        /**
         * 输入完毕后的回调
         */
        void onInputCompleted(CharSequence s);
    }
}